package org.btallarm.math;

import java.lang.reflect.Array;

import org.btallarm.json.ArrayField;
import org.btallarm.json.JSONMappingInfo;
import org.btallarm.json.JSONMappingType;


public class DelayLine<T> {
	@JSONMappingInfo(isRequired = true, objectType = JSONMappingType.JSON_ARRAY)
	@ArrayField(defaultCapacity = 10, enclosingType = JSONMappingType.JSON_DOUBLE)
	private T []data;
	
	@JSONMappingInfo(isRequired = true, objectType = JSONMappingType.JSON_INTEGER)
	private Integer head;

	@JSONMappingInfo(isRequired = true, objectType = JSONMappingType.JSON_INTEGER)
	private Integer tail;
	
	public T[] getData() {
		return data;
	}

	public void setData(T[] data) {
		this.data = data;
	}

	public Integer getHead() {
		return head;
	}

	public void setHead(Integer head) {
		this.head = head;
	}

	public Integer getTail() {
		return tail;
	}

	public void setTail(Integer tail) {
		this.tail = tail;
	}

	public DelayLine(Class<T> clazz, int capacity) {
		data = (T[]) Array.newInstance(clazz, capacity);
		head = 0;
		tail = capacity - 1;
	}
	
	public void push(T newelement){
		int capacity = data.length;
		data[tail] = newelement;
		tail = (tail + 1) % capacity;
		if(tail == head){
			head = (head + 1) % capacity;
		}
	}
	
	public T getElementAt(int i){
		if(i >= data.length)
			throw new IndexOutOfBoundsException();
				
		int realIndex = (head + i) % data.length;
		return data[realIndex];	
	}
	
	public void setElementAt(T d, int i){
		if(i >= data.length)
			throw new IndexOutOfBoundsException();
				
		int realIndex = (head + i) % data.length;
		data[realIndex] = d;	
	}
	
}
